package com.jzsm.modules.sender.senderService.impl.email;

import com.alibaba.fastjson.JSON;
import com.jzsm.modules.sender.enums.ChannelTypeEnum;
import com.jzsm.common.annotation.Channel;
import com.jzsm.common.utils.AssertUtils;
import com.jzsm.common.utils.StringUtils;
import com.jzsm.modules.sender.pojo.PushChannelAccount;
import com.jzsm.modules.sender.bo.accountConfig.EmailaccountConfigBo;
import com.jzsm.modules.sender.senderService.AbstractMessageSender;
import com.jzsm.modules.sender.senderService.impl.email.utils.EmailUtils;
import com.jzsm.modules.sender.vo.MailMessageVo;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.experimental.FieldDefaults;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.UrlResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;

/**
 * 邮件渠道
 */
@Slf4j
@Component
@Channel(ChannelTypeEnum.EMAIL)
@AllArgsConstructor
@FieldDefaults(level = AccessLevel.PRIVATE)
public class EmailMessageSender extends AbstractMessageSender {

    /**
     * @param message 信息
     * @param account 通道
     * @return
     */
    @Override
    public String sendMessage(String message, PushChannelAccount account) {
        return run(message, account);
    }

    private String run(String message, PushChannelAccount account) {
        return run(EmailUtils.makeMailSender(getAccountConfig(account)), message);
    }

    private String run(JavaMailSenderImpl javaMailSender, String message) {
        MailMessageVo messageObj = JSON.parseObject(message, MailMessageVo.class);

        Map<String, String> attachment = messageObj.getAttachment();
        MultipartFile[] files = messageObj.getFiles();

        // 附件邮件
        if (
                Objects.nonNull(messageObj.getAttachment()) && !attachment.isEmpty() ||
                        Objects.nonNull(files) && files.length > 0
        ) {
            javaMailSender.send(makeMimeMessage(javaMailSender.createMimeMessage(), messageObj));
        } else {
            // 文本邮件
            javaMailSender.send(makeSimpleEmailMessage(message));
        }
        return "";
    }

    /**
     * 创建附件 邮件消息体
     *
     * @param mimeMessage
     * @param messageObj
     * @return
     */
    private MimeMessage makeMimeMessage(MimeMessage mimeMessage, MailMessageVo messageObj) {
        Map<String, String> attachmentFilePaths = messageObj.getAttachment();
        MultipartFile[] files = messageObj.getFiles();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            /**
             * 接收人
             */
            helper.setTo(messageObj.getTo());
            /**
             * 邮件主题
             */
            helper.setSubject(messageObj.getSubject());
            /**
             * 抄送人
             */
            if (StringUtils.isNotBlank(messageObj.getCc())) {
                helper.setCc(messageObj.getCc());
            }
            /**
             * 邮件内容
             */
            helper.setText(messageObj.getText());

            // 添加多个附件链接
            if (!attachmentFilePaths.isEmpty()) {
                for (String key : attachmentFilePaths.keySet()) {
                    String path = attachmentFilePaths.get(key);
                    UrlResource urlResource = new UrlResource(new URL(path));
                    helper.addAttachment(path, urlResource);
                }
            }
            // 添加多个 文件
            if (files.length > 0) {
                for (MultipartFile file : files) {
                    helper.addAttachment(file.getOriginalFilename(), file);
                }
            }

        } catch (MessagingException | MalformedURLException e) {
            log.error(e.getMessage());
            AssertUtils.throwError(e.getMessage());
        }
        return mimeMessage;
    }

    /**
     * 构造 发送内容
     *
     * @param message
     * @return
     */
    private SimpleMailMessage makeSimpleEmailMessage(String message) {
        MailMessageVo messageObj = JSON.parseObject(message, MailMessageVo.class);

        SimpleMailMessage messageTemp = new SimpleMailMessage();
        /**
         * 接收人
         */
        messageTemp.setTo(messageObj.getTo());
        /**
         * 邮件主题
         */
        messageTemp.setSubject(messageObj.getSubject());
        /**
         * 抄送人
         */
        if (StringUtils.isNotBlank(messageObj.getCc())) {
            messageTemp.setCc(messageObj.getCc());
        }
        /**
         * 邮件内容
         */
        messageTemp.setText(messageObj.getText());
        return messageTemp;
    }

    private EmailaccountConfigBo getAccountConfig(PushChannelAccount setting) {
        String accountConfig = setting.getAccountConfig();
        AssertUtils.isNotBlank("邮件配置不允许为空！", accountConfig);
        return JSON.parseObject(accountConfig, EmailaccountConfigBo.class);
    }
}
